import { ChatMessage, ConversationContext } from './types';

// 扩展的聊天消息接口，用于持久化存储
export interface StoredChatMessage extends ChatMessage {
  // 消息类型（普通对话、自主发言、系统消息）
  messageType: 'conversation' | 'autonomous' | 'system';
  
  // 消息触发原因
  trigger?: 'player_approach' | 'player_message' | 'environment_change';
  
  // 相关的游戏上下文
  gameContext?: {
    playerPosition: { x: number; y: number; z: number };
    timeOfDay: string;
    weather: string;
  };
  
  // 消息情感色彩
  emotion?: 'happy' | 'sad' | 'angry' | 'neutral' | 'excited' | 'scared';
  
  // 是否已读
  isRead: boolean;
  
  // 消息重要性
  importance: 'low' | 'medium' | 'high';
}

// 聊天存储配置
export interface ChatStorageConfig {
  maxMessages: number;
  storageKey: string;
  autoCleanup: boolean;
  compressionEnabled: boolean;
}

// 聊天存储统计信息
export interface ChatStorageStats {
  totalMessages: number;
  messagesByEntity: Record<string, number>;
  oldestMessage: number;
  newestMessage: number;
  storageSize: number;
}

/**
 * 聊天记录持久化存储类
 * 负责管理聊天记录的本地存储、检索和清理
 */
export class ChatStorage {
  private config: ChatStorageConfig;
  private cache: Map<string, StoredChatMessage[]> = new Map();
  private isInitialized = false;

  constructor(config?: Partial<ChatStorageConfig>) {
    this.config = {
      maxMessages: 100,
      storageKey: 'webcraft_chat_history',
      autoCleanup: true,
      compressionEnabled: false,
      ...config
    };
  }

  /**
   * 初始化存储系统
   */
  async initialize(): Promise<void> {
    if (this.isInitialized) return;

    try {
      await this.loadAllHistory();
      this.isInitialized = true;
      console.log('ChatStorage initialized successfully');
    } catch (error) {
      console.error('Failed to initialize ChatStorage:', error);
      // 如果加载失败，重新初始化存储
      await this.resetStorage();
      this.isInitialized = true;
    }
  }

  /**
   * 保存聊天消息
   * 实现需求 10.1: 对话记录应该实时保存
   */
  async saveMessage(message: ChatMessage, options?: {
    messageType?: StoredChatMessage['messageType'];
    trigger?: StoredChatMessage['trigger'];
    gameContext?: StoredChatMessage['gameContext'];
    emotion?: StoredChatMessage['emotion'];
    importance?: StoredChatMessage['importance'];
  }): Promise<void> {
    if (!this.isInitialized) {
      await this.initialize();
    }

    const storedMessage: StoredChatMessage = {
      ...message,
      messageType: options?.messageType || 'conversation',
      trigger: options?.trigger,
      gameContext: options?.gameContext,
      emotion: options?.emotion || 'neutral',
      isRead: false,
      importance: options?.importance || 'medium'
    };

    // 获取实体的消息历史
    const entityKey = this.getEntityKey(message.entityId, message.entityType);
    let entityHistory = this.cache.get(entityKey) || [];

    // 添加新消息
    entityHistory.push(storedMessage);

    // 自动清理旧消息
    if (this.config.autoCleanup && entityHistory.length > this.config.maxMessages) {
      entityHistory = this.cleanupOldMessages(entityHistory, this.config.maxMessages);
    }

    // 更新缓存
    this.cache.set(entityKey, entityHistory);

    // 持久化到本地存储
    await this.persistToStorage();

    console.log(`Message saved for ${entityKey}:`, storedMessage.content.substring(0, 50));
  }

  /**
   * 加载聊天历史
   * 实现需求 10.2: 应该能够加载历史聊天记录
   */
  async loadHistory(entityId?: string, entityType?: string, limit?: number): Promise<StoredChatMessage[]> {
    if (!this.isInitialized) {
      await this.initialize();
    }

    if (entityId && entityType) {
      // 加载特定实体的历史
      const entityKey = this.getEntityKey(entityId, entityType);
      const history = this.cache.get(entityKey) || [];
      return limit ? history.slice(-limit) : history;
    } else {
      // 加载所有历史记录
      const allMessages: StoredChatMessage[] = [];
      for (const messages of this.cache.values()) {
        allMessages.push(...messages);
      }
      
      // 按时间戳排序
      allMessages.sort((a, b) => a.timestamp - b.timestamp);
      
      return limit ? allMessages.slice(-limit) : allMessages;
    }
  }

  /**
   * 清理旧消息
   * 实现需求 10.3: 聊天记录过多时应该自动清理最旧的记录
   */
  cleanupOldMessages(messages: StoredChatMessage[], maxCount: number): StoredChatMessage[] {
    if (messages.length <= maxCount) {
      return messages;
    }

    // 保留最新的消息，删除最旧的
    const cleanedMessages = messages.slice(-maxCount);
    
    console.log(`Cleaned up ${messages.length - cleanedMessages.length} old messages`);
    return cleanedMessages;
  }

  /**
   * 自动清理所有实体的旧消息
   */
  async performAutoCleanup(): Promise<void> {
    if (!this.config.autoCleanup) return;

    let totalCleaned = 0;
    
    for (const [entityKey, messages] of this.cache.entries()) {
      if (messages.length > this.config.maxMessages) {
        const originalCount = messages.length;
        const cleanedMessages = this.cleanupOldMessages(messages, this.config.maxMessages);
        this.cache.set(entityKey, cleanedMessages);
        totalCleaned += originalCount - cleanedMessages.length;
      }
    }

    if (totalCleaned > 0) {
      await this.persistToStorage();
      console.log(`Auto cleanup completed: removed ${totalCleaned} old messages`);
    }
  }

  /**
   * 清除所有聊天记录
   * 实现需求 10.4: 玩家清除游戏数据时聊天记录也应该被清除
   */
  async clearAllHistory(): Promise<void> {
    this.cache.clear();
    
    try {
      localStorage.removeItem(this.config.storageKey);
      localStorage.removeItem(`${this.config.storageKey}_backup`);
      console.log('All chat history cleared');
    } catch (error) {
      console.error('Failed to clear chat history from storage:', error);
      throw new Error('清除聊天记录失败');
    }
  }

  /**
   * 清除特定实体的聊天记录
   */
  async clearEntityHistory(entityId: string, entityType: string): Promise<void> {
    const entityKey = this.getEntityKey(entityId, entityType);
    this.cache.delete(entityKey);
    await this.persistToStorage();
    console.log(`Cleared history for ${entityKey}`);
  }

  /**
   * 获取存储统计信息
   */
  getStorageStats(): ChatStorageStats {
    let totalMessages = 0;
    const messagesByEntity: Record<string, number> = {};
    let oldestMessage = Date.now();
    let newestMessage = 0;

    for (const [entityKey, messages] of this.cache.entries()) {
      totalMessages += messages.length;
      messagesByEntity[entityKey] = messages.length;

      for (const message of messages) {
        if (message.timestamp < oldestMessage) {
          oldestMessage = message.timestamp;
        }
        if (message.timestamp > newestMessage) {
          newestMessage = message.timestamp;
        }
      }
    }

    // 计算存储大小（估算）
    const storageData = this.serializeData();
    const storageSize = new Blob([storageData]).size;

    return {
      totalMessages,
      messagesByEntity,
      oldestMessage: totalMessages > 0 ? oldestMessage : 0,
      newestMessage: totalMessages > 0 ? newestMessage : 0,
      storageSize
    };
  }

  /**
   * 导出聊天记录
   */
  async exportHistory(): Promise<string> {
    const allMessages = await this.loadHistory();
    const exportData = {
      version: '1.0',
      exportTime: Date.now(),
      messages: allMessages,
      stats: this.getStorageStats()
    };

    return JSON.stringify(exportData, null, 2);
  }

  /**
   * 导入聊天记录
   */
  async importHistory(data: string): Promise<void> {
    try {
      const importData = JSON.parse(data);
      
      if (!importData.messages || !Array.isArray(importData.messages)) {
        throw new Error('Invalid import data format');
      }

      // 清除现有数据
      this.cache.clear();

      // 导入消息
      for (const message of importData.messages) {
        if (this.isValidStoredMessage(message)) {
          const entityKey = this.getEntityKey(message.entityId, message.entityType);
          let entityHistory = this.cache.get(entityKey) || [];
          entityHistory.push(message);
          this.cache.set(entityKey, entityHistory);
        }
      }

      // 持久化
      await this.persistToStorage();
      console.log(`Imported ${importData.messages.length} messages`);
    } catch (error) {
      console.error('Failed to import chat history:', error);
      throw new Error('导入聊天记录失败');
    }
  }

  /**
   * 标记消息为已读
   */
  async markMessagesAsRead(entityId: string, entityType: string): Promise<void> {
    const entityKey = this.getEntityKey(entityId, entityType);
    const messages = this.cache.get(entityKey);
    
    if (messages) {
      let hasChanges = false;
      for (const message of messages) {
        if (!message.isRead) {
          message.isRead = true;
          hasChanges = true;
        }
      }
      
      if (hasChanges) {
        await this.persistToStorage();
      }
    }
  }

  /**
   * 获取未读消息数量
   */
  getUnreadCount(entityId?: string, entityType?: string): number {
    if (entityId && entityType) {
      const entityKey = this.getEntityKey(entityId, entityType);
      const messages = this.cache.get(entityKey) || [];
      return messages.filter(msg => !msg.isRead).length;
    } else {
      let totalUnread = 0;
      for (const messages of this.cache.values()) {
        totalUnread += messages.filter(msg => !msg.isRead).length;
      }
      return totalUnread;
    }
  }

  /**
   * 私有方法：生成实体键
   */
  private getEntityKey(entityId?: string, entityType?: string): string {
    if (entityId && entityType) {
      return `${entityType}_${entityId}`;
    }
    return 'global';
  }

  /**
   * 私有方法：从本地存储加载所有历史记录
   */
  private async loadAllHistory(): Promise<void> {
    try {
      const data = localStorage.getItem(this.config.storageKey);
      if (!data) {
        console.log('No existing chat history found');
        return;
      }

      const parsedData = JSON.parse(data);
      
      // 验证数据格式
      if (typeof parsedData !== 'object' || !parsedData.entities) {
        throw new Error('Invalid storage format');
      }

      // 加载到缓存
      this.cache.clear();
      for (const [entityKey, messages] of Object.entries(parsedData.entities)) {
        if (Array.isArray(messages)) {
          const validMessages = (messages as any[]).filter(msg => this.isValidStoredMessage(msg));
          this.cache.set(entityKey, validMessages);
        }
      }

      console.log(`Loaded chat history for ${this.cache.size} entities`);
    } catch (error) {
      console.error('Failed to load chat history:', error);
      throw error;
    }
  }

  /**
   * 私有方法：持久化到本地存储
   */
  private async persistToStorage(): Promise<void> {
    try {
      const data = this.serializeData();
      
      // 创建备份
      const existingData = localStorage.getItem(this.config.storageKey);
      if (existingData) {
        localStorage.setItem(`${this.config.storageKey}_backup`, existingData);
      }

      // 保存新数据
      localStorage.setItem(this.config.storageKey, data);
    } catch (error) {
      console.error('Failed to persist chat history:', error);
      
      // 尝试恢复备份
      try {
        const backup = localStorage.getItem(`${this.config.storageKey}_backup`);
        if (backup) {
          localStorage.setItem(this.config.storageKey, backup);
        }
      } catch (restoreError) {
        console.error('Failed to restore backup:', restoreError);
      }
      
      throw new Error('保存聊天记录失败');
    }
  }

  /**
   * 私有方法：序列化数据
   */
  private serializeData(): string {
    const entities: Record<string, StoredChatMessage[]> = {};
    
    for (const [entityKey, messages] of this.cache.entries()) {
      entities[entityKey] = messages;
    }

    const data = {
      version: '1.0',
      timestamp: Date.now(),
      entities,
      config: this.config
    };

    return JSON.stringify(data);
  }

  /**
   * 私有方法：验证存储消息格式
   */
  private isValidStoredMessage(message: any): message is StoredChatMessage {
    return (
      message &&
      typeof message.id === 'string' &&
      typeof message.timestamp === 'number' &&
      typeof message.sender === 'string' &&
      typeof message.content === 'string' &&
      (message.sender === 'player' || message.sender === 'entity')
    );
  }

  /**
   * 私有方法：重置存储
   * 实现需求 10.5: 数据损坏时应该能够重新初始化聊天系统
   */
  private async resetStorage(): Promise<void> {
    console.warn('Resetting chat storage due to corruption');
    this.cache.clear();
    
    try {
      localStorage.removeItem(this.config.storageKey);
      localStorage.removeItem(`${this.config.storageKey}_backup`);
    } catch (error) {
      console.error('Failed to reset storage:', error);
    }
  }

  /**
   * 检查存储是否健康
   */
  async checkStorageHealth(): Promise<boolean> {
    try {
      // 尝试读写测试
      const testKey = `${this.config.storageKey}_health_check`;
      const testData = JSON.stringify({ test: true, timestamp: Date.now() });
      
      localStorage.setItem(testKey, testData);
      const retrieved = localStorage.getItem(testKey);
      localStorage.removeItem(testKey);
      
      return retrieved === testData;
    } catch (error) {
      console.error('Storage health check failed:', error);
      return false;
    }
  }

  /**
   * 获取配置
   */
  getConfig(): ChatStorageConfig {
    return { ...this.config };
  }

  /**
   * 更新配置
   */
  updateConfig(newConfig: Partial<ChatStorageConfig>): void {
    this.config = { ...this.config, ...newConfig };
  }

  /**
   * 销毁存储实例
   */
  dispose(): void {
    this.cache.clear();
    this.isInitialized = false;
  }
}

// 导出默认存储实例
export const chatStorage = new ChatStorage();